[HVM][SVM] Updated the SVM V_TPR register on MMIO writes to the VLAPIC TPR
authorTravis Betak <travis.betak@amd.com>
Wed, 31 Jan 2007 19:37:44 +0000 (19:37 +0000)
committerTravis Betak <travis.betak@amd.com>
Wed, 31 Jan 2007 19:37:44 +0000 (19:37 +0000)
The SVM architecture includes a virtual TPR register.  This patch
updates this register on MMIO writes to the HVM Virtual APIC.

VT does not have this register as far as I know so a stub is added in
the VT code.

Signed-off-by: Travis Betak <travis.betak@amd.com>
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vlapic.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/hvm.h

index b2637a78076f76e9f64d66adb0f1459734f16f3d..a35b84848df4b10d11ca6f49decdb6132f643f8f 100644 (file)
@@ -660,6 +660,13 @@ void svm_update_guest_cr3(struct vcpu *v)
     v->arch.hvm_svm.vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
 }
 
+static void svm_update_vtpr(struct vcpu *v, unsigned long value)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+
+    vmcb->vintr.fields.tpr = value & 0x0f;
+}
+
 unsigned long svm_get_ctrl_reg(struct vcpu *v, unsigned int num)
 {
     switch ( num )
@@ -1048,6 +1055,8 @@ int start_svm(void)
     hvm_funcs.update_host_cr3 = svm_update_host_cr3;
     hvm_funcs.update_guest_cr3 = svm_update_guest_cr3;
     
+    hvm_funcs.update_vtpr = svm_update_vtpr;
+
     hvm_funcs.stts = svm_stts;
     hvm_funcs.set_tsc_offset = svm_set_tsc_offset;
 
@@ -1939,6 +1948,7 @@ static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
 
     case 8:
         vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
+        vmcb->vintr.fields.tpr = value & 0x0F;
         break;
 
     default:
index 4ac13ba9c45341a561813867033e646c16e33ca5..b38dee2e853d1dc5189175b01b5e62245ca7fcab 100644 (file)
@@ -593,6 +593,7 @@ static void vlapic_write(struct vcpu *v, unsigned long address,
     {
     case APIC_TASKPRI:
         vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
+        hvm_update_vtpr(v, (val >> 4) & 0x0f);
         break;
 
     case APIC_EOI:
index c3a2ed4585b0d6c532bb6e84f271145689b7250d..8a8691c383efe7b89c49c462225b7a06e02f433f 100644 (file)
@@ -986,6 +986,11 @@ static void vmx_inject_exception(
         v->arch.hvm_vmx.cpu_cr2 = cr2;
 }
 
+static void vmx_update_vtpr(struct vcpu *v, unsigned long value)
+{
+    /* VMX doesn't have a V_TPR field */
+}
+
 /* Setup HVM interfaces */
 static void vmx_setup_hvm_funcs(void)
 {
@@ -1011,6 +1016,8 @@ static void vmx_setup_hvm_funcs(void)
     hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
     hvm_funcs.update_guest_cr3 = vmx_update_guest_cr3;
 
+    hvm_funcs.update_vtpr = vmx_update_vtpr;
+
     hvm_funcs.stts = vmx_stts;
     hvm_funcs.set_tsc_offset = vmx_set_tsc_offset;
 
index 953cc60b3c01d9ee14615bfb95ddf06288786e6e..1e8093dafaa102057f219616a241e9559ab9d33e 100644 (file)
@@ -114,6 +114,11 @@ struct hvm_function_table {
      */
     void (*update_guest_cr3)(struct vcpu *v);
 
+    /*
+     * Reflect the virtual APIC's value in the guest's V_TPR register
+     */
+    void (*update_vtpr)(struct vcpu *v, unsigned long value);
+
     /*
      * Update specifics of the guest state:
      * 1) TS bit in guest cr0 
@@ -203,6 +208,12 @@ hvm_update_host_cr3(struct vcpu *v)
     hvm_funcs.update_host_cr3(v);
 }
 
+static inline void
+hvm_update_vtpr(struct vcpu *v, unsigned long value)
+{
+    hvm_funcs.update_vtpr(v, value);
+}
+
 void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3);
 
 void hvm_hypercall_page_initialise(struct domain *d,